import Pagination from "@/components/Pagination";
import TableToolBtns from "@/components/TableToolBtns";
import { mapGetters } from "vuex";

import { props, cellStyle, treeProps, headerCellStyle } from "./constant";

export default {
  name: "TablePublic",
  components: {
    Pagination,
    TableToolBtns,
  },
  props,
  computed: {
    ...mapGetters(["dictsMap"]),
  },
  data() {
    return {
      loading: false,
      columnsData: [], // 表头
      tableData: this.data, // 列表数据
      apiData: {}, // 接口数据
      cellStyle,
      treeProps,
      headerCellStyle, //表格表头样式
      paramsData: {},
      handleItem: "", //操作栏
      dragState: {
        start: -1, // 起始元素的index
        end: -1, //结束元素的index
        move: -1, // 移动鼠标时所覆盖的元素 index
        dragging: false, // 是否正在拖动
        direction: undefined, // 拖动方向
      },
    };
  },

  watch: {
    // 更改动作目前有：重置、搜索、分页，存在业务类型更改，迭代组件
    // 观测父组件参数更改 请求接口（存在问题： 双向绑定数据也会观测到）
    params(newData, oldData) {
      this.paramsData = newData;
    },

    // 通过人为触发更新列表
    resetTable: {
      handler(newData, oldData) {
        this.getData();
      },
      deep: true,
    },

    columns(newData, oldData) {
      this.initColumns();
    },
  },
  created() {
    this.paramsData = {
      ...this.params,
    };
    // 初始化
    if (typeof this.tableApi !== "function") {
      throw Error("table api 不能为空！");
    }

    //初始化表格
    this.initColumns();

    // 如直接主表带入数据，无需请求接口
    if (this.isInit) this.getData();
  },
  methods: {
    initColumns() {
      let parseColumnsData = JSON.parse(JSON.stringify(this.columns));
      parseColumnsData.some((item) => {
        if (item.prop == "handle") {
          this.handleItem = item;
          return;
        }
      });

      this.columnsData = parseColumnsData.filter(
        (item) => item.prop != "handle"
      );
    },

    getData() {
      this.loading = true;
      this.tableApi(this.paramsData)
        .then((res) => {
          if (this.diyTableFunc) {
            if (typeof this.diyTableFunc === "function") {
              const { data = {} } = this.diyTableFunc(res);
              const { records = [] } = data;
              this.tableData = records;
              this.apiData = data;
            } else {
              throw Error("diyTableDataFunc必须为函数！");
            }
            return;
          }
          const { data = {} } = res;
          const { records, total } = data;
          this.tableData = records;
          const { page, pageSize } = this.paramsData;
          this.apiData = {
            total,
            current: page,
            size: pageSize,
          };
          this.$emit("getSuccess", records);
        })
        .catch((err) => {
          console.log(err);
        })
        .finally(() => {
          setTimeout(() => {
            this.loading = false;
          }, 200);
        });
    },

    // 复选框变化事件
    selectionOnChange(data) {
      this.$emit("selectionOnChange", data);
    },

    // 操作按钮触发事件
    onBtnClick(data) {
      this.$emit("onBtnClick", data);
    },

    // 工具栏按钮触发事件
    onToolClick(data) {
      this.$emit("onToolClick", data);
    },

    // 分页变化事件
    paginaOnChange(data) {
      this.$emit("paginaOnChange", data);
    },

    // 单元格某一行被双击
    dblClick(data) {
      this.$emit("onDblClick", data);
    },

    // 选中全部数据
    onChoiceAll() {
      this.toggleRowAll(true);
    },

    // 清空选中数据
    onClearAll() {
      this.toggleRowAll(false);
    },

    toggleRowAll(state) {
      if (state) {
        this.onChoiceRow(this.tableData.map((item) => item[this.rowKey]));
      } else this.$refs[this.tableRef].clearSelection();
    },

    /**
     * 选中行数据
     * @param {Array 选中行数据} rows
     * @param {String 匹配key值，默认使用rowKey} key
     */
    onChoiceRow(rows, key = this.rowKey) {
      this.toggleRowSelection(rows, key, true);
    },

    // 取消选中行数据
    onClearRow(rows, key = this.rowKey) {
      this.toggleRowSelection(rows, key, false);
    },

    /**
     *
     * @param {Array 选中行数据} rows
     * @param {String 匹配key值，默认使用rowKey} key
     * @param {Boolean true选中 | false取消} state
     */
    toggleRowSelection(rows, key, state) {
      if (Array.isArray(rows)) {
        rows.forEach((row) => {
          const getItem = this.tableData.find((item) => item[key] === row);
          if (getItem)
            this.$refs[this.tableRef].toggleRowSelection(getItem, state);
        });
      } else {
        throw Error("传入的数据类型必须为数组！");
      }
    },

    //自定义表头渲染处理函数
    renderHeader(createElement, { column }) {
      return createElement(
        "div",
        {
          class: ["thead-cell"],
          on: {
            mousedown: ($event) => {
              this.handleMouseDown($event, column);
            },
            mouseup: ($event) => {
              this.handleMouseUp($event, column);
            },
            mousemove: ($event) => {
              this.handleMouseMove($event, column);
            },
          },
        },
        [
          // 添加 <a> 用于显示表头 label
          createElement("a", column.label),
          // 添加一个空标签用于显示拖动动画
          createElement("span", {
            class: ["virtual"],
          }),
        ]
      );
    },

    // 按下鼠标开始拖动
    handleMouseDown(e, column) {
      this.dragState.dragging = true;
      this.dragState.start = parseInt(column.columnKey);
      // 给拖动时的虚拟容器添加宽高
      let table = document.getElementsByClassName("w-table")[0];
      let virtual = document.getElementsByClassName("virtual");
      for (let item of virtual) {
        item.style.height = table.clientHeight - 1 + "px";
        item.style.width = item.parentElement.parentElement.clientWidth + "px";
      }
    },

    // 鼠标放开结束拖动
    handleMouseUp(e, column) {
      this.dragState.end = parseInt(column.columnKey); // 记录起始列
      this.dragColumn(this.dragState);
      // 初始化拖动状态
      this.dragState = {
        start: -1,
        end: -1,
        move: -1,
        dragging: false,
        direction: undefined,
      };
    },

    // 拖动中
    handleMouseMove(e, column) {
      if (this.dragState.dragging) {
        let index = parseInt(column.columnKey); // 记录起始列
        if (index - this.dragState.start !== 0) {
          this.dragState.direction =
            index - this.dragState.start < 0 ? "left" : "right"; // 判断拖动方向
          this.dragState.move = parseInt(column.columnKey);
        } else {
          this.dragState.direction = undefined;
        }
      } else {
        return false;
      }
    },

    // 拖动易位
    dragColumn({ start, end, direction }) {
      //表格拉伸时不做拖动处理
      if (start == -1) {
        return;
      }

      // 交换数组拖拽起始元素的位置
      let tempItem = this.columnsData[end];

      this.$set(this.columnsData, end, this.columnsData[start]);
      this.$set(this.columnsData, start, tempItem);
    },

    //动态修改class
    headerCellClassName({ column, columnIndex }) {
      return columnIndex - 1 === this.dragState.move
        ? `darg_active_${this.dragState.direction}`
        : "";
    },
    renderText(options) {
      const { item, header } = options;
      const { dict, prop, labelLinks } = header;
      const { row } = item;
      const val = row[prop];

      try {
        if (dict) {
          const { dictKey, dictColor } =
            this.$arrConverObj(this.dictsMap[dict], "dictValue")[val] || {};
          return {
            label: dictKey,
            color: dictColor,
          };
        } else {
          return {
            label: val,
          };
        }
      } catch (error) {
        return {
          label: val,
        };
      }
    },
  },
};
